#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "termino_merge.h"
#include "manejo_de_indices.h"



/*
 * Dado el archivo de lexico y el de indices, lee un registro del indice y calcula la long, del primer termino
 * 
 * 
 */ 
int obtener_longitud_de_termino_en_archivo_lexico(unsigned long int actual, FILE* archivo_indice,FILE* archivo_lexico){
	
	
	unsigned long int siguiente;
	int longitud_del_termino;
	
	
	//Leemos el siguiente termino
	int reg_leidos = fread(&siguiente, sizeof(unsigned long int), 1, archivo_indice);
	//Me fijo si es el fin del archivo (el ultimo termino seria)
	if (reg_leidos!= 1){
		fseek(archivo_lexico,0,SEEK_END);
		int long_arch = ftell(archivo_lexico);
		longitud_del_termino = long_arch - actual;
	}
	
	else{
		unsigned long int inicio_siguiente = siguiente;
		longitud_del_termino = inicio_siguiente - actual;
	}
	
	return longitud_del_termino;


}


/* 
 * BBin en archivo; no son tantos parametros, son nombres largos
 * Devuelve el indice si encontro el termino, -1 si no lo encontro.
 */
unsigned long int busqueda_binaria_en_archivo(char* termino, unsigned long int inicio, unsigned long int fin, FILE* archivo_indice,FILE* archivo_lexico){
	int long_reg = sizeof(unsigned long int);
	unsigned long int puntero_medio;
	unsigned long int medio =( (fin+inicio)/long_reg)/2;
	

	
	
	long int fin_control = (long int)fin;
	long int inicio_control = (long int)inicio;
	
	
	//Long del lexico apra corte de control
	fseek(archivo_lexico,0,SEEK_END);
	unsigned long int largo_lexico = ftell(archivo_lexico);
	
	//Tengo que castear a long porque si se van a negativos, con unsigned no anda
	if(inicio_control<=fin_control ){
		//Leemos el registro del medio 
		fseek(archivo_indice,medio*long_reg,SEEK_SET);
		fread(&puntero_medio, long_reg, 1, archivo_indice);
		
		int long_del_termino = obtener_longitud_de_termino_en_archivo_lexico(puntero_medio, archivo_indice, archivo_lexico);
		
		//Leemos el termino del archivo de lexico
		fseek(archivo_lexico,puntero_medio,SEEK_SET);
		//Si el termino excede el archivo,
		if (puntero_medio + long_del_termino >largo_lexico) return -1;
		char* termino_posicion_medio = malloc(sizeof(char)*(long_del_termino+1));
		fread(termino_posicion_medio,sizeof(char),long_del_termino,archivo_lexico);
		termino_posicion_medio[long_del_termino]='\0';
	
		//La busqueda per se
		if(strcmp(termino, termino_posicion_medio)<0){
			free(termino_posicion_medio);
			return busqueda_binaria_en_archivo(termino, inicio, medio*long_reg-long_reg, archivo_indice,archivo_lexico);
		}
		else if(strcmp(termino, termino_posicion_medio)>0){
				free(termino_posicion_medio);
				return busqueda_binaria_en_archivo(termino, medio*long_reg+long_reg, fin, archivo_indice,archivo_lexico);
			 }
			 else{ 
				 //Lo encontre; devuelvo el indice
			 	 free(termino_posicion_medio);
				 return medio;
			 }
		//No lo encontre.
		return -1;
	}
	return -1;
}

